/*
    Copyright (c) 2009 Pavol Malosek a.k.a. malo

    This file is part of ComComLib.

    ComComLib is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.

    ComComLib is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef __API_HPP_INCLUDED__
#define __API_HPP_INCLUDED__

#include <sys/types.h>
#include <sys/socket.h>
#include <poll.h>
#include <vector>

#include <lcc/device.hpp>
#include <lcc/device_Rxxxx.hpp>
#include <lcc/command.hpp>
#include <lcc/logger.hpp>

namespace lcc
{

    class api_t
    {
    public:

        //  Creates an api object to communicate with user aplication.
        //  Starts new thread to communicate with device on selected tty_.
        //  TODO: maybe comm try and comm timeout shoud be supplied here?
        api_t (void);

        //  Destroy I/O thread.
        ~api_t (void);

        //  Intialize serial port. Send bogus command and read error code.
        //  Return logger_id associated with tty.
        int create_logger (logger_type_t logger_type_, const char *tty_);

        //  Delete device object from logger_t structure and set status to 
        //  logger_destroyed.
        void destroy_logger (unsigned int logger_id_);
        
        //  Tries to open tty and issue bogus command, waits for status 
        //  message from logger.
        void touch_logger (unsigned int logger_id_);

        //  Read logger touch response.
        bool touch_logger_ok (unsigned int logger_id_);
        
        //  Read logger service memory into the device object.
        void read_service_memory (unsigned int logger_id_);
        
        //  Read service memory response.
        bool read_service_memory_ok (unsigned int logger_id_);

        //  Read and parse recorded values.
        void read_records (unsigned int logger_id_);

        //  Read records ok.
        bool read_records_ok (unsigned int logger_id_);

        //  Start online continuous measuring, interval_ in [s]
        void start_online_measure (unsigned int logger_id_, size_t interval_);

        //  Start online measure ok.
        bool start_online_measure_ok (unsigned int logger_id_);

        //  Check if command finished.
        bool ready (int logger_id_);

        //  Fill device info structure, note that read_service_memory
        //  has to be issued before.
        bool get_device_info (unsigned int logger_id_, 
            device_info_t *device_info_);

        // get records from logger.
        std::list<record_t> get_records (unsigned int logger_id_);
    private:
        //  Worker thread.
        static void *io_routine (void *arg_);

        //  Main loop.
        void loop (void);

        //  Send command to the I/O thread.
        void send_command (unsigned int logger_id_, 
            logger_command_name_t command_name_, uint16_t addr_ = 0, 
            size_t size_ = 0);

        //  Check if we have logger in loggers vector.
        inline bool logger_exist (unsigned int logger_id_)
        {
            if (loggers.size () > logger_id_ && 
                loggers [logger_id_].state != logger_destroyed) {
                return true;
            } else {
                return false;
            }
        }

        //  Check if command finished and returns true if 
        //  cmd_status == status_ok.
        bool is_command_status_ok (unsigned int logger_id_, 
            logger_command_name_t command_name_);

        //  Pollset
        pollfd pollset;

        //  I/O thread
        pthread_t io_thread;

        //  Logger devices.
        std::vector <logger_t> loggers;

        //  Loggers vector mutex.
        pthread_mutex_t loggers_mutex;

        //  Read/write sid of the socket
        int r;
        int w;
    };
}
#endif

